home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / basics / macx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  22.4 KB  |  797 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /** header ******************************************************************/
  18.  
  19. /*
  20.  * $Source$
  21.  * $Revision$
  22.  * $Date$
  23.  * $Author$
  24.  *
  25.  * creator: Brett Bainter
  26.  *
  27.  * purpose:
  28.  *    mixed model program demonstrating
  29.  *    ...multiple server connections
  30.  *    ...placing apps in non-default visuals
  31.  *    ...workprocs
  32.  *    ...working with XImages
  33.  *
  34.  * compiling:
  35.  *    cc -float -prototypes -O macx.c -o macx \
  36.  *    -s -lXirisw -lXm_s -lXt_s -lgl_s -lX11_s -lm -lc_s -lPW
  37.  *
  38.  * operating:
  39.  *    usage: macx [remote-display-spec]
  40.  *
  41.  * description:
  42.  *
  43.  * For this program the term "mac" represents a hypothetical x server running
  44.  * on a mac which happens to support a 24 bit TrueColor visual.
  45.  */
  46.  
  47. /** notes *******************************************************************/
  48.  
  49. /*
  50.  * - this seems to have a slight bug, but i haven't been able to locate it.
  51.  *   sometimes when it is started it hangs after opening up just the sgi
  52.  *   side of things.  it's hard to reproduce but does happen occasionally.
  53.  */
  54.  
  55. /** includes ****************************************************************/
  56.  
  57. #include <stdio.h>            /* standard */
  58. #include <Xm/Xm.h>            /* for motif */
  59. #include <Xm/DrawingA.h>        /* motif widget */
  60. #include <Xm/Form.h>            /* motif widget */
  61. #include <Xm/Frame.h>            /* motif widget */
  62. #include <Xm/PushB.h>            /* motif widget */
  63. #include <Xm/RowColumn.h>        /* motif widget */
  64. #include <Xm/Separator.h>        /* motif widget */
  65. #include <X11/Xirisw/GlxMDraw.h>    /* gl widget */
  66.  
  67. /** defines *****************************************************************/
  68.  
  69. /* c environment */
  70. #define global
  71.  
  72. /* colors */
  73. #define RGB_BACKGROUND        0x00555555
  74.  
  75. /** typedefs ****************************************************************/
  76. /** prototypes **************************************************************/
  77.  
  78. extern void main(int argc, char *argv[], char *envp[]);
  79.  
  80. /* setup */
  81. static void create_sgi_app(int *argc, char *argv[]);
  82. static void create_mac_app(int *argc, char *argv[]);
  83. static void install_colormaps(Widget top_level, Widget glw);
  84.  
  85. /* callbacks (gl widget) */
  86. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data);
  87. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data);
  88. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data);
  89. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data);
  90.  
  91. /* callbacks (canvas) */
  92. static void cb_can_expose(Widget w, XtPointer client_data, XtPointer call_data);
  93. static void cb_can_resize(Widget w, XtPointer client_data, XtPointer call_data);
  94.  
  95. /* callbacks (misc) */
  96. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data);
  97. static void cb_xfer(Widget w, XtPointer client_data, XtPointer call_data);
  98.  
  99. /* work procedures */
  100. static Boolean wp_anim(XtPointer client_data);
  101.  
  102. /* etc */
  103. static void glw_resize(void);
  104. static void glw_save(void);
  105. static void glw_transfer(void);
  106. static void canvas_load(void);
  107.  
  108. /* drawing */
  109. static void draw_frame(char *ops);
  110. static void model_cube_shaded(void);
  111.  
  112. /** variables ***************************************************************/
  113.  
  114. /* mixed-model configuration */
  115. static GLXconfig glx_config[] = {
  116.     {GLX_NORMAL, GLX_RGB, TRUE},
  117.     {GLX_NORMAL, GLX_DOUBLE, TRUE},
  118.     {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  119.     {0, 0, 0},
  120. };
  121.  
  122. /* application context for all display connections */
  123. static XtAppContext app_context;
  124.  
  125. static struct {            /* SGI CONNECTION */
  126.     Display *dsp;        /* display ref */
  127.     int screen;            /* the default one */
  128.     Widget app_shell;        /* first widget */
  129.     GC gc;            /* graphics context */
  130.     /**/
  131.     Widget glw;            /* can do gl rendering in this guy */
  132.     int im_width, im_height;    /* image size */
  133.     float im_aspect;        /* image width to height */ 
  134.     unsigned long *im_data;    /* malloc'ed array for image data */
  135. } sgi1;
  136.  
  137. static struct {            /* MAC CONNECTION */
  138.     Display *dsp;        /* display ref */
  139.     int screen;            /* the default one */
  140.     Widget app_shell;        /* first widget */
  141.     GC gc;            /* graphics context */
  142.     /**/
  143.     XVisualInfo vinfo;        /* for finding desired visual */
  144.     Visual *visual;        /* hopefully we get one we want */
  145.     Colormap cmap;        /* colormap which jives with visual */
  146.     Widget canvas;        /* for holding image */
  147.     XImage *x_image;        /* handle to the image we use for transfer */
  148.     int im_width, im_height;    /* image size */
  149.     float im_aspect;        /* image width to height */ 
  150.     unsigned long *im_data;    /* malloc'ed array for image data */
  151. } mac1;
  152.  
  153. /** functions ***************************************************************/
  154.  
  155. /*
  156.  * main - program entry point.
  157.  */
  158. global void main(
  159.     int argc,            /* argument count */
  160.     char *argv[],        /* argument vector */
  161.     char *envp[]        /* environment pointer */
  162. )
  163. {
  164.     /* setup the intrinsics */
  165.     XtToolkitInitialize();
  166.  
  167.     /* create our single application context */
  168.     app_context = XtCreateApplicationContext();
  169.  
  170.     /* setup each app */
  171.     create_sgi_app(&argc, argv);
  172.     create_mac_app(&argc, argv);
  173.  
  174.     /* realize the apps, creating the actual x windows */
  175.     XtRealizeWidget(sgi1.app_shell);
  176.     install_colormaps(sgi1.app_shell, sgi1.glw);
  177.     XtRealizeWidget(mac1.app_shell);
  178.  
  179.     /* create graphics context now that windows are available */
  180.     mac1.gc = XCreateGC(mac1.dsp, XtWindow(mac1.canvas), 0L, NULL);
  181.  
  182.     /* setup initial gl image area now that sizes are known */
  183.     glw_resize();
  184.  
  185.     /* enter the event loop */
  186.     XtAppMainLoop(app_context);
  187. }
  188.  
  189.  
  190. /*- support: setup ---------------------------------------------------------*/
  191. /*
  192.  * create_sgi_app -
  193.  */
  194. static void create_sgi_app(int *argc, char *argv[])
  195. {
  196.     XtWorkProcId wpid_anim;    /* animation work proc */
  197.     Widget form;        /* surrounds app */
  198.     Widget rowcol;        /* manages input buttons */
  199.     Widget button[2];        /* buttons */
  200.     Widget separator;        /* between input and output */
  201.     Widget frame;        /* to surround gl widget */
  202.     Arg args[15];        /* for name/value pairs */
  203.     int n;            /* reusable indices */
  204.  
  205.     /* connect to display */
  206.     n = 0;
  207.     sgi1.dsp = XtOpenDisplay(app_context, "", argv[0], "Sgi", args, n,
  208.     argc, argv
  209.     );
  210.     sgi1.screen = DefaultScreen(sgi1.dsp);
  211.  
  212.     /* create application shell */
  213.     n = 0;
  214.     XtSetArg(args[n], XmNgeometry, "400x300+100+350"); n++;
  215.     XtSetArg(args[n], XmNtitle, "SGI Display"); n++;
  216.     sgi1.app_shell = XtAppCreateShell("sgi", "Sgi",
  217.     applicationShellWidgetClass, sgi1.dsp, args, n
  218.     );
  219.  
  220.     /* create container for app */
  221.     n = 0;
  222.     form = XmCreateForm(sgi1.app_shell, "form", args, n);
  223.     XtManageChild(form);
  224.  
  225.     /* create the command area */
  226.     n = 0;
  227.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  228.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  229.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  230.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  231.     rowcol = XmCreateRowColumn(form, "rowcol", args, n);
  232.     XtManageChild(rowcol);
  233.  
  234.     /* create the command area buttons */
  235.     n = 0;
  236.     button[0] = XmCreatePushButton(rowcol, "Quit", args, n);
  237.     XtAddCallback(button[0], XmNactivateCallback, cb_quit, NULL);
  238.     button[1] = XmCreatePushButton(rowcol, "Send", args, n);
  239.     XtAddCallback(button[1], XmNactivateCallback, cb_xfer, "sgi-put");
  240.     XtManageChildren(button, XtNumber(button));
  241.  
  242.     /* create separator between command area and output area */
  243.     n = 0;
  244.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  245.     XtSetArg(args[n], XmNleftWidget, rowcol); n++;
  246.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  247.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  248.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  249.     separator = XmCreateSeparator(form, "separator", args, n);
  250.     XtManageChild(separator);
  251.  
  252.     /* create the output area */
  253.     /* create the frame */
  254.     n = 0;
  255.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  256.     XtSetArg(args[n], XmNleftWidget, separator); n++;
  257.     XtSetArg(args[n], XmNleftOffset, 5); n++;
  258.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  259.     XtSetArg(args[n], XmNrightOffset, 5); n++;
  260.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  261.     XtSetArg(args[n], XmNbottomOffset, 5); n++;
  262.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  263.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  264.     XtSetArg(args[n], XmNshadowThickness, 6); n++;
  265.     frame = XmCreateFrame(form, "frame", args, n);
  266.     XtManageChild(frame);
  267.  
  268.     /* create the gl widget */
  269.     n = 0;
  270.     XtSetArg(args[n], GlxNglxConfig, glx_config); n++;
  271.     XtSetArg(args[n], XmNborderWidth, 0); n++;
  272.     sgi1.glw = GlxCreateMDraw(frame, "glw", args, n);
  273.     XtManageChild(sgi1.glw);
  274.     XtAddCallback(sgi1.glw, GlxNexposeCallback, cb_gl_expose, 0);
  275.     XtAddCallback(sgi1.glw, GlxNresizeCallback, cb_gl_resize, 0);
  276.     XtAddCallback(sgi1.glw, GlxNginitCallback, cb_gl_ginit, 0);
  277.     XtAddCallback(sgi1.glw, GlxNinputCallback, cb_gl_input, 0);
  278.  
  279.     /* setup work procedure */
  280.     wpid_anim = XtAppAddWorkProc(app_context, wp_anim, sgi1.glw);
  281. }
  282.  
  283.  
  284. /*
  285.  * create_mac_app -
  286.  *
  287.  * This app does not use the gl widget.  It is expected to run on a vanilla
  288.  * X/Motif system.  We attempt to place this application in a 24 bit TrueColor
  289.  * visual.
  290.  */
  291. static void create_mac_app(int *argc, char *argv[])
  292. {
  293.     #define VISDEPTH        24
  294.     #define VISCLASS        TrueColor
  295.     #define LOCDISP        ""
  296.     #define MACDISP        "einstein:0.0"
  297.     /**/
  298.     Widget form;        /* surrounds app */
  299.     Widget rowcol;        /* manages input buttons */
  300.     Widget button[2];        /* buttons */
  301.     Widget separator;        /* between input and output */
  302.     Widget frame;        /* to surround the canvas */
  303.     Arg args[15];        /* for name/value pairs */
  304.     int n;            /* reusable indices */
  305.     char *dsp_name;        /* could go to remote machine */
  306.  
  307.     /* connect to display */
  308.     dsp_name = *argc<=1? NULL : argv[1];
  309.     n = 0;
  310.     mac1.dsp = XtOpenDisplay(app_context, dsp_name, argv[0], "Mac", args, n,
  311.     argc, argv
  312.     );
  313.     if (mac1.dsp == (Display *) NULL) {
  314.     fprintf(stderr, "ERROR: can't connect to MAC X server %s\n",
  315.         XDisplayName(dsp_name)
  316.     );
  317.     exit(-1);
  318.     }
  319.     mac1.screen = DefaultScreen(mac1.dsp);
  320.  
  321.     /* setup visual ----------------------------------------*/
  322.     if (
  323.     XMatchVisualInfo(mac1.dsp, mac1.screen, VISDEPTH, VISCLASS, &mac1.vinfo)
  324.     == 0
  325.     ) {
  326.     fprintf(stderr, "%s: cannot find needed visual.\n", argv[0]);
  327.     exit(-1);
  328.     }
  329.     mac1.visual = mac1.vinfo.visual;
  330.     /*------------------------------------------------------*/
  331.  
  332.     /* setup colormap --------------------------------------*/
  333.     mac1.cmap = XCreateColormap(mac1.dsp, RootWindow(mac1.dsp, mac1.screen),
  334.     mac1.visual, AllocNone
  335.     );
  336.     /*------------------------------------------------------*/
  337.  
  338.     /* create application shell */
  339.     n = 0;
  340.     XtSetArg(args[n], XmNdepth, VISDEPTH); n++;
  341.     XtSetArg(args[n], XmNcolormap, mac1.cmap); n++;
  342.     XtSetArg(args[n], XmNvisual, mac1.visual); n++;
  343.     XtSetArg(args[n], XmNgeometry, "400x300+550+350"); n++;
  344.     XtSetArg(args[n], XmNtitle, "MAC Display"); n++;
  345.     mac1.app_shell = XtAppCreateShell("mac", "Mac",
  346.     applicationShellWidgetClass, mac1.dsp, args, n
  347.     );
  348.  
  349.     /* create container for app */
  350.     n = 0;
  351.     form = XmCreateForm(mac1.app_shell, "form", args, n);
  352.     XtManageChild(form);
  353.  
  354.     /* create the command area */
  355.     n = 0;
  356.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  357.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  358.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  359.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  360.     rowcol = XmCreateRowColumn(form, "rowcol", args, n);
  361.     XtManageChild(rowcol);
  362.  
  363.     /* create the command area buttons */
  364.     n = 0;
  365.     button[0] = XmCreatePushButton(rowcol, "Quit", args, n);
  366.     XtAddCallback(button[0], XmNactivateCallback, cb_quit, NULL);
  367.     button[1] = XmCreatePushButton(rowcol, "Grab", args, n);
  368.     XtAddCallback(button[1], XmNactivateCallback, cb_xfer, "mac-get");
  369.     XtManageChildren(button, XtNumber(button));
  370.  
  371.     /* create separator between command area and output area */
  372.     n = 0;
  373.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  374.     XtSetArg(args[n], XmNleftWidget, rowcol); n++;
  375.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  376.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  377.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  378.     separator = XmCreateSeparator(form, "separator", args, n);
  379.     XtManageChild(separator);
  380.  
  381.     /* create the output area */
  382.     /* create the frame */
  383.     n = 0;
  384.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  385.     XtSetArg(args[n], XmNleftWidget, separator); n++;
  386.     XtSetArg(args[n], XmNleftOffset, 5); n++;
  387.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  388.     XtSetArg(args[n], XmNrightOffset, 5); n++;
  389.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  390.     XtSetArg(args[n], XmNbottomOffset, 5); n++;
  391.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  392.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  393.     XtSetArg(args[n], XmNshadowThickness, 6); n++;
  394.     frame = XmCreateFrame(form, "frame", args, n);
  395.     XtManageChild(frame);
  396.  
  397.     /* create the drawing area */
  398.     n = 0;
  399.     XtSetArg(args[n], XmNbackground, RGB_BACKGROUND); n++;
  400.     mac1.canvas = XmCreateDrawingArea(frame, "canvas", args, n);
  401.     XtAddCallback(mac1.canvas, XmNexposeCallback, cb_can_expose, NULL);
  402.     XtAddCallback(mac1.canvas, XmNresizeCallback, cb_can_resize, NULL);
  403.     XtManageChild(mac1.canvas);
  404.  
  405.     /* create image structure which describes are image data */
  406.     /* note: we need this for refreshes of the canvas */
  407.     mac1.x_image = XCreateImage(
  408.     mac1.dsp, mac1.visual, VISDEPTH, ZPixmap, 0,
  409.     NULL, 1, 1,    /* dynamic */
  410.     32,        /* 16 works and 8 works too (??) */
  411.     0        /* dynamic */
  412.     );
  413. }
  414.  
  415.  
  416. /*
  417.  * install_colormaps - let the window manager know about our colormaps.
  418.  */
  419. static void install_colormaps(Widget top_level, Widget glw)
  420. {
  421.     Window overlay_win, popup_win, underlay_win;
  422.     Window window[5];
  423.     int i;
  424.  
  425.     XtVaGetValues(
  426.     glw,
  427.     GlxNoverlayWindow, &overlay_win,
  428.     GlxNpopupWindow, &popup_win,
  429.     GlxNunderlayWindow, &underlay_win,
  430.     NULL
  431.     );
  432.     i = 0;
  433.     if (overlay_win)
  434.     window[i++] = overlay_win;
  435.     if (popup_win)
  436.     window[i++] = popup_win;
  437.     if (underlay_win)
  438.     window[i++] = underlay_win;
  439.     window[i++] = XtWindow(glw);
  440.     window[i++] = XtWindow(top_level);
  441.     XSetWMColormapWindows(XtDisplay(top_level), XtWindow(top_level), window, i);
  442. }
  443.  
  444.  
  445. /*- support: callbacks (gl widget) -----------------------------------------*/
  446. /*
  447.  * cb_gl_expose - handle expose events for the gl widget.
  448.  */
  449. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data)
  450. {
  451.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  452.  
  453.     GLXwinset(XtDisplay(w), XtWindow(w));
  454.     draw_frame("cds");
  455. }
  456.  
  457.  
  458. /*
  459.  * cb_gl_resize - handle resize events for the gl widget.
  460.  */
  461. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data)
  462. {
  463.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  464.  
  465.     GLXwinset(XtDisplay(w), XtWindow(w));
  466.     glw_resize();
  467. }
  468.  
  469.  
  470. /*
  471.  * cb_gl_ginit - perform any necessary graphics initialization.
  472.  */
  473. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data)
  474. {
  475.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  476.  
  477.     GLXwinset(XtDisplay(w), XtWindow(w));
  478.  
  479.     shademodel(GOURAUD);
  480.     zbuffer(TRUE);
  481.     subpixel(TRUE);
  482.     lsetdepth(getgdesc(GD_ZMIN), getgdesc(GD_ZMAX));
  483.     mmode(MVIEWING);
  484.     perspective(300, glx->width/(float)glx->height, 1.0, 50.0);
  485.     polarview(10.0, 0, 0, 0);
  486.     frontbuffer(TRUE);
  487.     cpack(RGB_BACKGROUND);
  488.     clear();
  489.     frontbuffer(FALSE);
  490.     gflush();
  491. }
  492.  
  493.  
  494. /*
  495.  * cb_gl_input - handle input from a gl window.
  496.  */
  497. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data)
  498. {
  499.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  500.  
  501.     GLXwinset(XtDisplay(w), XtWindow(w));
  502. }
  503.  
  504.  
  505. /*- support: callbacks (gl widget) -----------------------------------------*/
  506. /*
  507.  * cb_can_expose -
  508.  */
  509. static void cb_can_expose(Widget w, XtPointer client_data, XtPointer call_data)
  510. {
  511.     canvas_load();
  512. }
  513.  
  514.  
  515. /*
  516.  * cb_can_resize -
  517.  */
  518. static void cb_can_resize(Widget w, XtPointer client_data, XtPointer call_data)
  519. {
  520. }
  521.  
  522.  
  523. /*- support: callbacks (misc) ----------------------------------------------*/
  524. /*
  525.  * cb_quit -
  526.  */
  527. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data)
  528. {
  529.     XDestroyImage(mac1.x_image);
  530.     XFreeGC(mac1.dsp, mac1.gc);
  531.     exit(0);
  532. }
  533.  
  534.  
  535. /*
  536.  * cb_xfer -
  537.  */
  538. static void cb_xfer(Widget w, XtPointer client_data, XtPointer call_data)
  539. {
  540.     GLXwinset(XtDisplay(sgi1.glw), XtWindow(sgi1.glw));
  541.     glw_save();
  542.     glw_transfer();
  543.     canvas_load();
  544. }
  545.  
  546.  
  547. /*- support: work procedures -----------------------------------------------*/
  548. /*
  549.  * wp_anim - do another frame of animation.
  550.  */
  551. static Boolean wp_anim(XtPointer client_data)
  552. {
  553.     Widget glw = (Widget) client_data;
  554.  
  555.     GLXwinset(XtDisplay(glw), XtWindow(glw));
  556.     draw_frame("cdsu");
  557.     return (False);
  558. }
  559.  
  560.  
  561. /*- support: etc -----------------------------------------------------------*/
  562. /*
  563.  * glw_resize - account for changes in the size of the gl widget.
  564.  */
  565. static void glw_resize(void)
  566. {
  567.     Arg args[5];
  568.     int n;
  569.     Dimension w, h;
  570.  
  571.     /* obtain gl widget size */
  572.     n = 0;
  573.     XtSetArg(args[n], XmNwidth, &w); n++;
  574.     XtSetArg(args[n], XmNheight, &h); n++;
  575.     XtGetValues(sgi1.glw, args, n);
  576.     sgi1.im_width = w;
  577.     sgi1.im_height = h;
  578.     sgi1.im_aspect = sgi1.im_width / (float) sgi1.im_height;
  579.     #if 0
  580.     printf("glw_resize(%d x %d)\n", sgi1.im_width, sgi1.im_height);
  581.     #endif
  582.  
  583.     /* setup area to save image to */
  584.     if (sgi1.im_data != (unsigned long *) NULL) {
  585.     free((void *) sgi1.im_data);
  586.     }
  587.     sgi1.im_data = (unsigned long *) malloc(w*h*sizeof(sgi1.im_data[0]));
  588.     if ((char *)sgi1.im_data == NULL) {
  589.     fprintf(stderr, "ERROR: malloc failed for gl widget image array.\n");
  590.     exit(-1);
  591.     }
  592.  
  593.     /* setup gl for new size */
  594.     viewport(0, sgi1.im_width-1, 0, sgi1.im_height-1);
  595.     perspective(300, sgi1.im_aspect, 1.0, 50.0);
  596. }
  597.  
  598.  
  599. /*
  600.  * glw_save - copy the gl widget image to the image data array.
  601.  */
  602. static void glw_save(void)
  603. {
  604.     lrectread(0, 0, sgi1.im_width-1, sgi1.im_height-1, sgi1.im_data);
  605.     gflush();
  606. }
  607.  
  608.  
  609. /*
  610.  * glw_transfer - convert sgi image data to an X format.
  611.  *
  612.  * Our job for a 24 bit visual is simple: we just flip the image to account
  613.  * for the difference in the X and GL y axes.  Because of the simplicity of
  614.  * this we can convert the image in place without the need to allocate a
  615.  * destination image.  No big whoop.
  616.  *
  617.  * If the vanilla visual is 8 bit PseudoColor then big whoop.
  618.  */
  619. static void glw_transfer(void)
  620. {
  621.     register int i, j;
  622.     register int lo_row, hi_row;
  623.     register unsigned long temp;
  624.     int midpoint = sgi1.im_height/2;
  625.  
  626.     /* flip image in place */
  627.     for (i=0; i<midpoint; i++) {
  628.     hi_row = i*sgi1.im_width;
  629.     lo_row = ((sgi1.im_height-1)-i)*sgi1.im_width;
  630.     for (j=0; j<sgi1.im_width; j++) {
  631.         /* swap pixel from lo to hi rows */
  632.         temp = sgi1.im_data[lo_row+j];
  633.         sgi1.im_data[lo_row+j] = sgi1.im_data[hi_row+j];
  634.         sgi1.im_data[hi_row+j] = temp;
  635.     }
  636.     }
  637.  
  638.     /* the mac image is really our image area */
  639.     mac1.im_width = sgi1.im_width;
  640.     mac1.im_height = sgi1.im_height;
  641.     mac1.im_aspect = sgi1.im_aspect;
  642.     mac1.im_data = sgi1.im_data;
  643.     mac1.x_image->width = mac1.im_width;
  644.     mac1.x_image->height = mac1.im_height;
  645.     mac1.x_image->bytes_per_line = mac1.im_width*sizeof(mac1.im_data[0]);
  646.     mac1.x_image->data = (char *) mac1.im_data;
  647. }
  648.  
  649.  
  650. /*
  651.  * canvas_load - load the mac image into the canvas.
  652.  */
  653. static void canvas_load(void)
  654. {
  655.     XClearWindow(mac1.dsp, XtWindow(mac1.canvas));
  656.     if (mac1.x_image->data != NULL) {
  657.     XPutImage(
  658.         mac1.dsp, XtWindow(mac1.canvas), mac1.gc, mac1.x_image,
  659.         0, 0, 0, 0, mac1.im_width, mac1.im_height
  660.     );
  661.     }
  662.     XFlush(mac1.dsp);
  663. }
  664.  
  665.  
  666. /*- support: drawing -------------------------------------------------------*/
  667. /*
  668.  * draw_frame -
  669.  */
  670. static void draw_frame(char *ops)
  671. {
  672.     static Angle rx = 0;
  673.     static Angle ry = 0;
  674.     static Angle rz = 0;
  675.  
  676.     for (; *ops != '\0'; ops++) {
  677.     switch (ops[0]) {
  678.     case 'c':        /* clear */
  679.         czclear(RGB_BACKGROUND, getgdesc(GD_ZMAX));
  680.         break;
  681.     case 'd':        /* draw */
  682.         pushmatrix();
  683.         rotate(rz, 'z');
  684.         rotate(ry, 'y');
  685.         rotate(rx, 'x');
  686.         model_cube_shaded();
  687.         popmatrix();
  688.         break;
  689.     case 's':        /* swap */
  690.         swapbuffers();
  691.         gflush();
  692.         break;
  693.     case 'u':        /* update */
  694.         /* next angle */
  695.         rx = (rx + 10) % 3600;
  696.         ry = (ry + 10) % 3600;
  697.         rz = (rz + 10) % 3600;
  698.         break;
  699.     default:
  700.         break;
  701.     }
  702.     }
  703. }
  704.  
  705.  
  706. /*
  707.  * model_cube_shaded - draw a smooth shaded cube.
  708.  *
  709.  * - borrowed from ivan.
  710.  */
  711. static void model_cube_shaded(void)
  712. {
  713.     static long v1[4][3] = {
  714.     {-1, -1,  1},
  715.     { 1, -1,  1},
  716.     { 1,  1,  1},
  717.     {-1,  1,  1},
  718.     };
  719.     static long v2[4][3] = {
  720.     {-1, -1, -1},
  721.     {-1,  1, -1},
  722.     { 1,  1, -1},
  723.     { 1, -1, -1},
  724.     };
  725.     static long colors1[] = {
  726.     0x000000FF,
  727.     0x00FF0000,
  728.     0x0000FF00,
  729.     0x00FFFF00,
  730.     };
  731.     static long colors2[] = {
  732.     0x0000FFFF,
  733.     0x00FF00FF,
  734.     0x00FFFFFF,
  735.     0x0FF00000,
  736.     };
  737.     /**/
  738.     register int i;
  739.     
  740.     bgnpolygon();
  741.     for(i=0; i<4; i++) {
  742.         cpack(colors1[i]);
  743.         v3i(v1[i]);
  744.     }
  745.     endpolygon();
  746.     bgnpolygon();
  747.     for(i=0; i<4; i++) {
  748.         cpack(colors2[i]);
  749.         v3i(v2[i]);
  750.     }
  751.     endpolygon();
  752.     
  753.     bgnpolygon();
  754.     cpack(colors1[1]);
  755.     v3i(v1[1]);
  756.     cpack(colors1[2]);
  757.     v3i(v1[2]);
  758.     cpack(colors2[2]);
  759.     v3i(v2[2]);
  760.     cpack(colors2[3]);
  761.     v3i(v2[3]);
  762.     endpolygon();
  763.     bgnpolygon();
  764.     cpack(colors1[0]);
  765.     v3i(v1[0]);
  766.     cpack(colors1[3]);
  767.     v3i(v1[3]);
  768.     cpack(colors2[1]);
  769.     v3i(v2[1]);
  770.     cpack(colors2[0]);
  771.     v3i(v2[0]);
  772.     endpolygon();
  773.  
  774.     bgnpolygon();
  775.     cpack(colors1[2]);
  776.     v3i(v1[2]);
  777.     cpack(colors1[3]);
  778.     v3i(v1[3]);
  779.     cpack(colors2[1]);
  780.     v3i(v2[1]);
  781.     cpack(colors2[2]);
  782.     v3i(v2[2]);
  783.     endpolygon();
  784.     bgnpolygon();
  785.     cpack(colors1[1]);
  786.     v3i(v1[1]);
  787.     cpack(colors1[0]);
  788.     v3i(v1[0]);
  789.     cpack(colors2[0]);
  790.     v3i(v2[0]);
  791.     cpack(colors2[3]);
  792.     v3i(v2[3]);
  793.     endpolygon();
  794. }
  795.  
  796. /** eof *********************************************************************/
  797.